#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日志配置管理器

提供全局统一的日志管理功能，避免每个文件都使用自己的日志方法。

使用方法:
    from settings import get_logger
    
    logger = get_logger(__name__)
    logger.info('这是一条信息日志')
    logger.error('这是一条错误日志')

作者: AI Assistant
创建时间: 2024
"""

import logging
import logging.handlers
import os
from pathlib import Path
from typing import Optional, Dict
from .base_config import LoggerConfig


class LoggerManager:
    """日志管理器"""
    
    _instance = None
    _loggers: Dict[str, logging.Logger] = {}
    _initialized = False
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if not self._initialized:
            self.config = LoggerConfig()
            self._setup_logging()
            LoggerManager._initialized = True
    
    def update_config(self, config: LoggerConfig):
        """更新日志配置"""
        self.config = config
        self._setup_logging()
        # 重新配置所有已存在的logger
        for name, logger in self._loggers.items():
            self._configure_logger(logger, name)
    
    def _setup_logging(self):
        """设置日志配置"""
        # 确保日志目录存在
        log_dir = Path(self.config.file_path).parent
        log_dir.mkdir(parents=True, exist_ok=True)
        
        # 设置根日志级别
        logging.getLogger().setLevel(getattr(logging, self.config.level.upper()))
    
    def _configure_logger(self, logger: logging.Logger, name: str):
        """配置单个logger"""
        # 清除现有的handlers
        for handler in logger.handlers[:]:
            logger.removeHandler(handler)
            handler.close()
        
        # 设置日志级别
        logger.setLevel(getattr(logging, self.config.level.upper()))
        
        # 创建格式化器
        formatter = logging.Formatter(
            fmt=self.config.format,
            datefmt=self.config.date_format
        )
        
        # 控制台输出
        if self.config.console_output:
            console_handler = logging.StreamHandler()
            console_handler.setLevel(getattr(logging, self.config.level.upper()))
            console_handler.setFormatter(formatter)
            logger.addHandler(console_handler)
        
        # 文件输出
        if self.config.file_output:
            # 使用RotatingFileHandler实现日志轮转
            file_handler = logging.handlers.RotatingFileHandler(
                filename=self.config.file_path,
                maxBytes=self.config.max_size * 1024 * 1024,  # 转换为字节
                backupCount=self.config.backup_count,
                encoding='utf-8'
            )
            file_handler.setLevel(getattr(logging, self.config.level.upper()))
            file_handler.setFormatter(formatter)
            logger.addHandler(file_handler)
        
        # 防止日志传播到根logger
        logger.propagate = False
    
    def get_logger(self, name: str) -> logging.Logger:
        """获取或创建logger"""
        if name not in self._loggers:
            logger = logging.getLogger(name)
            self._configure_logger(logger, name)
            self._loggers[name] = logger
        
        return self._loggers[name]
    
    def set_level(self, level: str):
        """设置全局日志级别"""
        self.config.level = level.upper()
        for logger in self._loggers.values():
            logger.setLevel(getattr(logging, level.upper()))
            for handler in logger.handlers:
                handler.setLevel(getattr(logging, level.upper()))
    
    def add_file_handler(self, logger_name: str, file_path: str, level: str = None):
        """为指定logger添加额外的文件处理器"""
        if logger_name in self._loggers:
            logger = self._loggers[logger_name]
            
            # 确保文件目录存在
            Path(file_path).parent.mkdir(parents=True, exist_ok=True)
            
            # 创建文件处理器
            file_handler = logging.handlers.RotatingFileHandler(
                filename=file_path,
                maxBytes=self.config.max_size * 1024 * 1024,
                backupCount=self.config.backup_count,
                encoding='utf-8'
            )
            
            # 设置级别
            handler_level = level or self.config.level
            file_handler.setLevel(getattr(logging, handler_level.upper()))
            
            # 设置格式
            formatter = logging.Formatter(
                fmt=self.config.format,
                datefmt=self.config.date_format
            )
            file_handler.setFormatter(formatter)
            
            # 添加到logger
            logger.addHandler(file_handler)
    
    def remove_handlers(self, logger_name: str):
        """移除指定logger的所有处理器"""
        if logger_name in self._loggers:
            logger = self._loggers[logger_name]
            for handler in logger.handlers[:]:
                logger.removeHandler(handler)
                handler.close()


# 全局日志管理器实例
_logger_manager = LoggerManager()


def get_logger(name: str) -> logging.Logger:
    """
    获取logger实例
    
    Args:
        name (str): logger名称，通常使用 __name__
        
    Returns:
        logging.Logger: 配置好的logger实例
        
    Example:
        >>> from settings import get_logger
        >>> logger = get_logger(__name__)
        >>> logger.info('这是一条信息日志')
    """
    return _logger_manager.get_logger(name)


def update_logger_config(config: LoggerConfig):
    """
    更新全局日志配置
    
    Args:
        config (LoggerConfig): 新的日志配置
    """
    _logger_manager.update_config(config)


def set_log_level(level: str):
    """
    设置全局日志级别
    
    Args:
        level (str): 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    """
    _logger_manager.set_level(level)


def add_file_handler(logger_name: str, file_path: str, level: str = None):
    """
    为指定logger添加额外的文件处理器
    
    Args:
        logger_name (str): logger名称
        file_path (str): 文件路径
        level (str, optional): 日志级别
    """
    _logger_manager.add_file_handler(logger_name, file_path, level)


def setup_logger_from_config(config: LoggerConfig):
    """
    从配置对象设置日志
    
    Args:
        config (LoggerConfig): 日志配置对象
    """
    global _logger_manager
    _logger_manager.update_config(config)


# 便捷的日志装饰器
def log_function_call(logger_name: str = None, level: str = 'DEBUG'):
    """
    记录函数调用的装饰器
    
    Args:
        logger_name (str, optional): logger名称，默认使用函数所在模块
        level (str): 日志级别
    """
    def decorator(func):
        def wrapper(*args, **kwargs):
            logger = get_logger(logger_name or func.__module__)
            log_level = getattr(logging, level.upper())
            
            logger.log(log_level, f'调用函数: {func.__name__}, 参数: args={args}, kwargs={kwargs}')
            
            try:
                result = func(*args, **kwargs)
                logger.log(log_level, f'函数 {func.__name__} 执行成功')
                return result
            except Exception as e:
                logger.error(f'函数 {func.__name__} 执行失败: {e}')
                raise
        
        return wrapper
    return decorator


# 便捷的异常记录函数
def log_exception(logger_name: str, message: str = None):
    """
    记录异常信息
    
    Args:
        logger_name (str): logger名称
        message (str, optional): 额外的错误信息
    """
    logger = get_logger(logger_name)
    if message:
        logger.exception(message)
    else:
        logger.exception('发生异常')